package com.tools.app;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Message;
import android.provider.Settings;
import android.support.multidex.MultiDex;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;

import com.appsflyer.AppsFlyerConversionListener;
import com.appsflyer.AppsFlyerLib;
import com.hm.ads.sdk.HmAdsSDK;
import com.hm.adsbuisiness.AdsContants;
import com.hm.adtools.AdToolsModule;
import com.hm.adtools.bean.ReInstallCheckInfo;
import com.hm.adtools.bean.TrueUserInfo;
import com.hm.app.BuildConfig;
import com.hm.app.R;
import com.hm.base.android.mob.ATutorialManager;
import com.hm.base.android.mob.MLog;
import com.hm.base.android.mob.MobBeanManager;
import com.hm.base.android.mob.config.DeviceConfig;
import com.hm.base.android.mob.service.ActionException;
import com.hm.base.android.mob.task.mark.ATaskMark;
import com.hm.base.android.mob.util.DeviceUtil;
import com.hm.base.android.mob.util.PermissionUtil;
import com.tools.ad.ADConstant;
import com.tools.ad.EntranceType;
import com.tools.ad.bean.AdGARecord;
import com.tools.ad.bean.AppInfo;
import com.tools.ad.manager.InnerHookManager;
import com.tools.ad.util.AppUtils;
import com.tools.app.cache.SmartMonitorCache;
import com.tools.app.manager.AppBeanManager;
import com.tools.app.manager.AppManager;
import com.tools.app.sdk.GoogleAnalyticsImpl;
import com.tools.app.store.AppConfig;
import com.tools.app.store.AppSharedPrefManager;
import com.tools.app.task.AppServiceWrapper;
import com.tools.app.task.AppTaskMarkPool;
import com.tools.app.task.mark.SubmitReferrerTaskMark;
import com.tools.app.ui.activity.AppOuterActivity;
import com.tools.app.ui.activity.AutoCleanActivity;
import com.tools.app.ui.activity.SmartMonitorActivity;
import com.tools.app.ui.view.SwipeGuideWindow;
import com.tools.app.ui.view.WeatherGuideWindow;
import com.tools.app.util.EncryptUtil;
import com.tools.cleanmaster.CleanApplication;

import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;

import static com.tools.ad.ADConstant.PROTOCOL_TYPE.INVISIBLE_TYPE;

/**
 * desc:
 * date: 2018/4/11
 * author: ancun
 */

public class AppApplication extends CleanApplication {

    private AppBeanManager mAppBeanManager;

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }

    @Override
    protected MobBeanManager createBeanManager() {
        mAppBeanManager = new AppBeanManager(this);
        return mAppBeanManager;
    }

    @Override
    protected void initMApplication() throws Exception {
        super.initMApplication();
        initAppsFlyer();
        initActivityLifeCycle();
    }

    @Override
    public void receiveResult(ATaskMark taskMark, ActionException e, Object o) {
        if (taskMark instanceof SubmitReferrerTaskMark) {

            if (taskMark.getTaskStatus() == ATaskMark.HANDLE_OVER) {
                //上报成功
                getSharedPrefManager().saveReferrer("");

                //MLog.e("CoolerApp", "receiveResult HANDLE_OVER ");

            } else if (taskMark.getTaskStatus() == ATaskMark.HANDLE_ERROR) {

                //MLog.e("CoolerApp", "receiveResult HANDLE_ERROR ");
            }
        }
    }

    @Override
    protected AppBeanManager getBeanManager() {
        return mAppBeanManager;
    }

    @Override
    public AppSharedPrefManager getSharedPrefManager() {
        return getBeanManager().getAppSharedPrefManager();
    }

    @Override
    public AppManager getMobManager() {
        return getBeanManager().getAppManager();
    }

    @Override
    public AppServiceWrapper getServiceWrapper() {
        return getBeanManager().getAppServiceWrapper();
    }

    @Override
    public AppTaskMarkPool getTaskMarkPool() {
        return getBeanManager().getAppTaskMarkPool();
    }

    @Override
    public AppConfig getMobConfig() {
        return getBeanManager().getAppConfig();
    }

    @Override
    public ATutorialManager getTutorialManager() {
        return null;
    }

    @Override
    protected void initContextConfig() throws Exception {
        DeviceConfig deviceConfig = getDeviceConfig();
        initDeviceConfig(deviceConfig);
        initDevelop();
    }

    @Override
    protected void initMobConfig() throws Exception {
        AppConfig mobConfig = getMobConfig();
        initSecurityConfig(mobConfig);

        //尝试上报referrer
        String referrer = getSharedPrefManager().getReferrer();
        if (getSharedPrefManager().getKeyOpenDeveloper()) {
            Log.i("referrer", referrer);
        }

        if (!TextUtils.isEmpty(referrer)) {
            long rts = getSharedPrefManager().getRTS();
            SubmitReferrerTaskMark taskMark = getTaskMarkPool().getSubmitReferrerTaskMark();
            getServiceWrapper().submitReferrer(this, taskMark, referrer, rts);
        }
    }

    private boolean handleRecordMsg(Message msg) {
        if (msg.obj != null && (msg.obj instanceof AdGARecord)) {
            AdGARecord record = (AdGARecord) msg.obj;
            if (record.getValue() >= 0) {
                recordGA(record.getCategoryId(), record.getActionId(), record.getLabelId(), record.getValue());
            } else {
                recordGA(record.getCategoryId(), record.getActionId(), record.getLabelId());
            }

            if (msg.what == R.id.msg_ad_ga_record) {
                msg.arg1 = R.id.msg_mob_message_end;
                return true;
            }
        }
        return false;
    }

    @Override
    protected void subSwitchHandleMessage(Message msg) {
        super.subSwitchHandleMessage(msg);

        if (handleRecordMsg(msg)) {
            return;
        }

        switch (msg.what) {
            case R.id.msg_ad_sdk_init_finish:

                break;

            case R.id.msg_cleaner_develop_mode_enable:
                getSharedPrefManager().setKeyOpenDeveloper(true);
                break;

            case R.id.msg_receive_referrer_url:
                String referrer = (String) msg.obj;
                recordGA(GAConstants.C_DATA, GAConstants.A_REFERRER, referrer);

                //保存referrer 与 time
                long rts = System.currentTimeMillis();
                getSharedPrefManager().saveReferrer(referrer);
                getSharedPrefManager().saveReferrerForGA(referrer);
                getSharedPrefManager().saveRTS(rts);

                //上报新装，这里将label写死(CustomDimension 中会有渠道信息)，方便服务端分析
                recordGA(GAConstants.C_DATA, GAConstants.A_NEW_INSTALL, GAConstants.L_CHANNEL_KEY);

                //上报服务器
                if (PermissionUtil.checkPermission(this, Manifest.permission.READ_PHONE_STATE)) {
                    SubmitReferrerTaskMark taskMark = getTaskMarkPool().getSubmitReferrerTaskMark();
                    getServiceWrapper().submitReferrer(this, taskMark, referrer, rts);
                }

                //如果是 Organic 用户，将开关置为关，需要用户手动开启
                //如果是非 Organic 用户，开关默认开，同时隐藏设置入口
                getADModule().getADSharedPrefManager().setSwipeAdEnable(!getADModule().isOrganicOrOtherChannel());

                //处理完成后不再传递
                msg.arg1 = R.id.msg_mob_message_end;
                break;

            case R.id.msg_app_submit_referrer:
                if (!getSharedPrefManager().getReferrer().isEmpty()) {
                    SubmitReferrerTaskMark taskMark = getTaskMarkPool().getSubmitReferrerTaskMark();
                    getServiceWrapper().submitReferrer(this, taskMark, getSharedPrefManager().getReferrer(), getSharedPrefManager().getRTS());
                }
                //处理完成后不再传递
                msg.arg1 = R.id.msg_mob_message_end;
                break;

            case R.id.msg_swipe_guide_show:
                SwipeGuideWindow swipeGuideWindow = new SwipeGuideWindow(this);
                swipeGuideWindow.show();
                break;

            case R.id.msg_weather_guide_show:
                WeatherGuideWindow weatherGuideWindow = new WeatherGuideWindow(this);
                weatherGuideWindow.show();
                break;

            case R.id.msg_weather_click_hook:
                getADModule().getAdSceneManager().load(EntranceType.WEATHER_FULL_SCREEN);
                break;

            case R.id.msg_swipe_load_ad_hook:
                getADModule().getAdSceneManager().load(EntranceType.SWIPE_REPLACE);
                break;

            case R.id.msg_swipe_replace_ad_loaded:
                try {
                    View adView = getADModule().getAdSceneManager().getAdView(EntranceType.SWIPE_REPLACE);
                    InnerHookManager.addAdToSwipe(adView);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                break;

            case R.id.msg_weather_load_ad_hook:
                getADModule().getAdSceneManager().load(EntranceType.WEATHER_REPLACE);
                break;

            case R.id.msg_weather_replace_ad_loaded:
                try {
                    View adView = getADModule().getAdSceneManager().getAdView(EntranceType.WEATHER_REPLACE);
                    InnerHookManager.addAdToWeather(adView);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                break;


            case R.id.msg_ad_smart_monitor_app_info:
                AppInfo appInfo = (AppInfo) msg.obj;
                getSmartMonitorCache().setAppInfo(appInfo);

                if (Intent.ACTION_PACKAGE_ADDED.equals(appInfo.getAction())) {
                    getADModule().getAdSceneManager().load(EntranceType.APP_INSTALL);
                } else if (Intent.ACTION_PACKAGE_REMOVED.equals(appInfo.getAction())) {
                    getADModule().getAdSceneManager().load(EntranceType.APP_UNINSTALL);
                }

                break;

            case R.id.msg_ad_app_scene_loaded:
                Intent smartMonitorActivityIntent = new Intent(this, SmartMonitorActivity.class);
                smartMonitorActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                smartMonitorActivityIntent.putExtra(ADConstant.AD_TYPE, msg.arg2);
                smartMonitorActivityIntent.putExtra(ADConstant.ENTRANCE_TYPE, (String) msg.obj);
                startActivity(smartMonitorActivityIntent);
                //处理完成后不再传递
                msg.arg1 = R.id.msg_mob_message_end;
                break;

            case R.id.msg_ad_auto_clean_scene_loaded:
                Intent realProtectActivityIntent = new Intent(this, AutoCleanActivity.class);
                realProtectActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(realProtectActivityIntent);
                //处理完成后不再传递
                msg.arg1 = R.id.msg_mob_message_end;
                break;

            case R.id.msg_receive_true_user_info:
                //是否是初次安装已经在sdk中判断如果不是初次安装不会去加载真实用户数据也就不会发这个消息了
                reportTrueUser();
                //处理完成后不再传递
                msg.arg1 = R.id.msg_mob_message_end;
                break;
            case R.id.msg_receive_reinstall_check_info:
                reportReInstallInfo();
                //处理完成后不再传递
                msg.arg1 = R.id.msg_mob_message_end;
                break;

            case R.id.msg_ad_need_activity:
                Intent appOuterIntent = new Intent(this, AppOuterActivity.class);
                appOuterIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(appOuterIntent);
                break;

            default:
                break;
        }
    }

    /**
     * 上报用户数据-只有非真实用户时才上报
     */
    private void reportTrueUser() {
        AdToolsModule adsModule = (AdToolsModule) getSubModule(AdToolsModule.MODULE_KEY);
        boolean isFirstRun = adsModule.getSystemSettingManager().isFirstRun();
        if (isFirstRun) {
            TrueUserInfo trueUserInfo = HmAdsSDK.getInstance().getTrueUserInfo();
            boolean isTrueUser = trueUserInfo.isTrueUser();
            if (!isTrueUser) {
                String spUserInfo = HmAdsSDK.getInstance().getSpUserInfo();
                recordGA(GAConstants.C_USER, GAConstants.A_TRUE_USER_INFO, spUserInfo);
            }
        }
    }

    /**
     * 上报用户数据-只有重复安装时才上报
     */
    private void reportReInstallInfo() {
        ReInstallCheckInfo reInstallCheckInfo = HmAdsSDK.getInstance().getReInstallCheckInfo();
        boolean isReInstall = reInstallCheckInfo.isReInstall();
        if (isReInstall) {
            recordGA(GAConstants.C_USER, GAConstants.A_REINSTALL_CHECK_INFO, reInstallCheckInfo.getUuid());
        }
    }

    public SmartMonitorCache getSmartMonitorCache() {
        return getBeanManager().getSmartMonitorCache();
    }

    @Override
    protected void globalBussnessHandleMessage(Message message) {

    }

    @Override
    public int getModulesConfig() {
        return R.xml.modules;
    }

    @Override
    public int getServiceParts() {
        return R.xml.services;
    }

    @Override
    public String getSessionId() {
        return null;
    }

    @Override
    public String getUserId() {
        return null;
    }

    @Override
    public boolean isSessionValid() {
        return false;
    }

    protected GoogleAnalyticsImpl getGoogleAnalytics() {
        return getBeanManager().getGoogleAnalytics();
    }

    /**
     * GA行为打点
     */
    public void recordGA(String categoryId, String actionId, String labelId) {
        if (MLog.debug) {
            Log.i(categoryId, actionId + ":" + labelId);
        }
        if (getGoogleAnalytics() == null) {
            return;
        }
        getGoogleAnalytics().record(categoryId, actionId, labelId);
    }

    /**
     * GA行为打点
     */
    public void recordGA(String categoryId, String actionId, String labelId, long v) {
        if (getGoogleAnalytics() == null) {
            return;
        }
        getGoogleAnalytics().record(categoryId, actionId, labelId, v);
    }

    /**
     * GA屏幕浏览日志
     *
     * @param screenName 页面名称  如没有定义则显示的是UI页面类名
     */
    public void recordScreenTrail(String screenName) {
        if (getGoogleAnalytics() == null) {
            return;
        }
        getGoogleAnalytics().recordScreenTrail(screenName);
    }

    private void initAppsFlyer() {
        try {
            //TODO af转化数据获取
            AppsFlyerConversionListener listener = new AppsFlyerConversionListener() {

                public void onInstallConversionDataLoaded(Map<String, String> conversionData) {

                    String conversion = conversionData.toString();
                    if (getSharedPrefManager().getKeyOpenDeveloper() || BuildConfig.DEBUG) {
                        Log.i("af_install", conversion);
                    }

                    //如果is_first_launch=true或者没有该信息，则打点
                    try {
                        if (Boolean.valueOf(conversionData.get("is_first_launch"))) {
                            recordGA(GAConstants.C_DATA, GAConstants.A_AF_INSTALL, conversion);
                        }
                    } catch (Exception e) {
                        recordGA(GAConstants.C_DATA, GAConstants.A_AF_INSTALL, conversion);
                    }

                    //从af的转化数据里获取campaign信息，取得cpro_后面的渠道标记，如果没有cpro_，则不使用渠道标记，使用gp广播中的信息
                    String channel = HmAdsSDK.getInstance().getReferrerChannel();
                    if ((channel.equals(AdsContants.ORGANIC_CHANNEL) || channel.equals(AdsContants.OTHER_CHANNEL)) && conversionData.containsKey("campaign")) {
                        channel = conversionData.get("campaign");
                        String start = com.tools.ad.BuildConfig.APP_ID + "_";
                        int index = channel.indexOf(start);
                        if (index >= 0) {
                            channel = channel.substring(index + start.length());
                            int i = channel.indexOf("_");
                            if (i > 0) {
                                channel = channel.substring(0, i);
                            }

                            HmAdsSDK.getInstance().setReferrerChannel(channel);

                            //如果是 Organic 用户，将开关置为关，需要用户手动开启
                            //如果是非 Organic 用户，开关默认开，同时隐藏设置入口

                            //正常情况下,这里应该是目标渠道推广用户
                            getADModule().getADSharedPrefManager().setSwipeAdEnable(!getADModule().isOrganicOrOtherChannel());
                        }
                    }

                    getSharedPrefManager().setAFInstallConversionData(conversion);
                }

                public void onInstallConversionFailure(String errorMessage) {
                    Log.d("AppsFlyerTest", "error getting conversion data: " + errorMessage);
                }

                @Override
                public void onAppOpenAttribution(Map<String, String> map) {
                    StringBuffer conversion = new StringBuffer();
                    Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
                    while (iterator.hasNext()) {
                        Map.Entry<String, String> entry = iterator.next();
                        conversion.append(entry.getKey()).append(":").append(entry.getValue());
                        if (iterator.hasNext()) {
                            conversion.append(",");
                        }
                    }

                    getSharedPrefManager().setAFOpenData(map.toString());
                }

                @Override
                public void onAttributionFailure(String s) {

                }

            };

            AppsFlyerLib.getInstance().init(AppConstant.APPFLYER_DEV_KEY, listener, this);
            AppsFlyerLib.getInstance().startTracking(this);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void initActivityLifeCycle() {
        AppUtils.registerActivityLifecycleCallbacks(this);
    }

    private void initDevelop() {
        if (getSharedPrefManager().getKeyOpenDeveloper() || BuildConfig.DEBUG) {
            HmAdsSDK.getInstance().setDevelopeMode();
        }

        if (BuildConfig.DEBUG) {
            HmAdsSDK.getInstance().setTestAd();
        }
    }

    @SuppressLint("MissingPermission")
    private void initDeviceConfig(DeviceConfig deviceConfig) throws Exception {
        AppSharedPrefManager coolerSharedPrefManager = getSharedPrefManager();
        if (PermissionUtil.checkPermission(this, Manifest.permission.READ_PHONE_STATE)) {
            // 设备id
            TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
            // imsi
            String imsi = tm.getSubscriberId();
            deviceConfig.setSimId(imsi);

            // imei
            String imei = coolerSharedPrefManager.getImei();
            if (imei == null) {
                imei = tm.getDeviceId();
                coolerSharedPrefManager.setImei(imei);
            }
            deviceConfig.setImei(imei);
        }

        // mac
        String mac = null;
        try {
            WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
            WifiInfo info = wifi.getConnectionInfo();
            mac = info.getMacAddress();
            deviceConfig.setMac(mac);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 手机型号名字(Nexus One)
        String model = Build.MODEL;
        deviceConfig.setModel(model);

        // 手机品牌
        String brand = Build.BRAND;
        deviceConfig.setBrand(brand);

        // 手机网络运营商名称
        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        // 运营商名称会加入到请求header中，由于okHttp不支持中文，防了防止出现中文请求失败，这里做一次encode
        String simOperatorName = URLEncoder.encode(telephonyManager.getSimOperatorName(), "UTF-8");
        deviceConfig.setCarrier(simOperatorName);

        // 版本
        PackageManager manager = getPackageManager();
        PackageInfo info = manager.getPackageInfo(getPackageName(), 0);
        if (info != null) {
            deviceConfig.setVersion(info.versionName);
            deviceConfig.setVersionCode(info.versionCode);
        } else {
            deviceConfig.setVersion("1.0");
            deviceConfig.setVersionCode(1);
        }

        // 固件版本
        String firmware = Build.VERSION.RELEASE;
        deviceConfig.setFirmware(firmware);

        // sdkversion
        String sdkVersion = Build.VERSION.SDK;
        deviceConfig.setSdkVersion(sdkVersion);

        // 硬件架构
        String abi = Build.CPU_ABI;
        abi = (abi == null || abi.trim().length() == 0) ? "" : abi;
        // 检视是否有第二类型，1.6没有这个字段
        String cpuAbi2 = DeviceUtil.getCpuAbi();
        cpuAbi2 = (cpuAbi2 == null || cpuAbi2.trim().length() == 0) ? null : cpuAbi2;
        if (cpuAbi2 != null) {
            abi = abi + "|" + cpuAbi2;
        }
        deviceConfig.setAbi(abi);

        WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics displayMetrics = new DisplayMetrics();
        Display display = windowManager.getDefaultDisplay();
        display.getMetrics(displayMetrics);
        // resolution
        int width = displayMetrics.widthPixels;
        int height = displayMetrics.heightPixels;
        deviceConfig.setResolution(width + "*" + height);

        // density (1.5 没有densityDpi这个字段)
        int density = DeviceUtil.getDensityDpi(displayMetrics);
        deviceConfig.setDensity(String.valueOf(density));

        //设置当前时区对比UTC的偏移量，单位毫秒
        int offsetValue = TimeZone.getDefault().getOffset(System.currentTimeMillis());
        deviceConfig.setTimeZoneOffset(offsetValue);

        String ANDROID_ID = Settings.System.getString(getContentResolver(), Settings.System.ANDROID_ID);
        deviceConfig.setAndroidId(ANDROID_ID);
    }

    private void initSecurityConfig(AppConfig mobConfig) {
        Locale locale = getResources().getConfiguration().locale;

        mobConfig.setAppId(EncryptUtil.decryptOffsetByte(AppConstant.APP_ID));
        mobConfig.setAppKey(EncryptUtil.decryptOffsetByte(AppConstant.APP_KEY));

        //服务端要求，上传的语言需要添加国家字段（zh-CN）
        mobConfig.setLanguage(locale.getLanguage() + "-" + locale.getCountry());

        if (com.tools.ad.BuildConfig.PROTOCOL_TYPE == INVISIBLE_TYPE) {
            mobConfig.setIsAppIdProtocol(true);
        }
    }
}
